<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2018 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\school\controller;

use cmf\controller\AdminBaseController;
use app\school\model\OrderModel;
use app\school\model\SchoolSubjectModel;
use app\school\model\SchoolLevelModel;
use app\school\model\SchoolClassModel;
use app\school\model\SchoolTeacherModel;
use app\school\model\SchoolCourseModel;
use app\school\model\UserStudentModel;
use wxapp\aes\Wxpay;
use wxapp\aes\WXBizDataCrypt;
use think\Db;

class AdminOrderController extends AdminBaseController
{    
    public function index()
    {
        $where=[];    
        $dwhere=[];    
        $swhere=[];
        $param = $this->request->param();     
        $status = $this->request->param('pay_status');       
        $pay_type = $this->request->param('pay_type');       

        if($status != null){
            $dwhere['a.pay_status'] = $status;           
        }
        if($pay_type != null){
            $dwhere['a.pay_type'] = $pay_type;           
        }

        if(!empty($param['course_id'])){
            $dwhere['a.course_id'] = $param['course_id'];
        }
        if(!empty($param['subject_id'])){
            $dwhere['b.subject_id'] = $param['subject_id'];
        }
        if(!empty($param['class_id'])){
            $dwhere['b.class_id'] = $param['class_id'];
        }
        if(!empty($param['teacher_id'])){
            $dwhere['b.teacher_id'] = $param['teacher_id'];
        }
       
        $field = 'a.*,b.id as courseid,b.title,b.subject_id,b.class_id,b.teacher_id ';

        $startTime = empty($param['start_time']) ? 0 : strtotime($param['start_time']);
        $endTime   = empty($param['end_time']) ? 0 : strtotime($param['end_time']);
        if (!empty($startTime) && !empty($endTime)) {
            $dwhere['a.create_time'] = [['>= time', $startTime], ['<= time', $endTime]];
        } else {
            if (!empty($startTime)) {
                $dwhere['a.create_time'] = ['>= time', $startTime];
            }
            if (!empty($endTime)) {
                $dwhere['a.create_time'] = ['<= time', $endTime];
            }
        }

        if(!empty($param['keyword'])){
            $dwhere['a.student_name'] = ['like','%'.$param['keyword'].'%'];
        }
       
        $join = [
            ['school_course b', 'a.course_id = b.id']
         ];
        $model = new OrderModel();
        $data = $model->alias('a')->field($field)
            ->join($join)
            ->where($dwhere)->order("a.id DESC")->paginate(10); 
        $data->appends($param); 
        
        $courseModel = new SchoolCourseModel();
        $courseList = $courseModel-> select();       
        $subjectModel = new SchoolSubjectModel();
        $subjectList = $subjectModel-> select();       
        $classModel = new SchoolClassModel();
        $classList = $classModel->  select();
        $teacherModel = new SchoolTeacherModel();
        $teacherList = $teacherModel-> select();

        $this->assign('start_time', isset($param['start_time']) ? $param['start_time'] : '');
        $this->assign('end_time', isset($param['end_time']) ? $param['end_time'] : '');
        $this->assign('pay_type', isset($param['pay_type']) ? $param['pay_type'] : '');
        $this->assign('course_id', isset($param['course_id']) ? $param['course_id'] : '');
        $this->assign('subject_id', isset($param['subject_id']) ? $param['subject_id'] : '');
        $this->assign('class_id', isset($param['class_id']) ? $param['class_id'] : '');
        $this->assign('teacher_id', isset($param['teacher_id']) ? $param['teacher_id'] : '');
        $this->assign('keyword', isset($param['keyword']) ? $param['keyword'] : '');
        $this->assign('pay_status', isset($param['pay_status']) ? $param['pay_status'] : '');

        $this->assign('courseList',$courseList);       
        $this->assign('subjectList',$subjectList);       
        $this->assign('classList',$classList);
        $this->assign('teacherList',$teacherList);  

        $this->assign('list',$data);
        $this->assign('page', $data->render());
        return $this->fetch();
    }

    public function courseList()
    {
        $param = $this->request->param();

        $model = new SchoolCourseModel();
        $data = $model->lists($param);             
        $data->appends($param);
        $subjectModel = new SchoolSubjectModel();
        $subjectList = $subjectModel-> select();       
        $classModel = new SchoolClassModel();
        $classList = $classModel->  select();
        $teacherModel = new SchoolTeacherModel();
        $teacherList = $teacherModel-> select();
        
        $this->assign('subject_id', isset($param['subject_id']) ? $param['subject_id'] : '');
        $this->assign('class_id', isset($param['class_id']) ? $param['class_id'] : '');
        $this->assign('teacher_id', isset($param['teacher_id']) ? $param['teacher_id'] : '');
        $this->assign('keyword', isset($param['keyword']) ? $param['keyword'] : '');

        $this->assign('subjectList',$subjectList);       
        $this->assign('classList',$classList);
        $this->assign('teacherList',$teacherList);  
        $this->assign('list',$data);
        $this->assign('page', $data->render());
        return $this->fetch();
    }

    public function addOrder()
    {
        $id = $this->request->param('id', 0, 'intval');
        $courseModel = new SchoolCourseModel();
        $data = $courseModel-> where('id',$id)->find(); 
        $timestamp = time();
        $orderModel = new OrderModel();
        $seats = $orderModel->where("course_id={$id} and (({$timestamp} - create_time <= 900 and pay_status != 3) or  pay_status = 1)" )->column('seat');      
      
        $this->assign('seats', implode(",", $seats));
        $this->assign('id',$id);
        $this->assign('data',$data);
        return $this->fetch();
    }
    

    public function addOrderSave()
    {
        $OrderModel = new OrderModel();
        $data = $this->request->param();     

        $data['pay_status'] = isset($data['pay_status']) ? $data['pay_status'] : '';

        $result = $this->validate($data, 'Order');
        if ($result !== true) {
            $this->error($result);
        }

        $timestamp = time();
        $orderModel = new OrderModel();
        $status = $orderModel->where("course_id={$data['course_id']} and seat={$data['seat']} and (({$timestamp} - create_time <= 900 and pay_status != 3) or  pay_status = 1)" )->find();    
        
        if ($status) {
            $this->error("添加失败，{$data['seat']}号座位已被选");
        }
        
        if($data['pay_status'] == 1){
            $data['pay_time'] = date('YmdHis');
        }
        
        $data['order_no'] = $this -> getOrderNo(); 
        $result = $OrderModel->allowField(true)->save($data);
        if($data['pay_status']==1) {
            Db::name('school_course')
            ->where('id','=',$data['course_id'])
            ->setInc('order_count',1);
        }
        
             
        if ($result === false) {
            $this->error('添加失败!');
        }
        if($data['pay_type']==1 || $data['pay_type']==2){
            $this->success('添加成功!', url('AdminOrder/index'));
        }
        $this->success('添加成功!', url('AdminOrder/microPay','id='.$OrderModel->id));

    }

    public function editOrder()
    {
        $order_id = $this->request->param('order_id', 0, 'intval');
        $orderModel = new OrderModel();
        $orderData = $orderModel->where("id",$order_id)->find();

        $courseModel = new SchoolCourseModel();
        $data = $courseModel-> where('id',$orderData['course_id'])->find(); 

        $courseList = $courseModel-> select();     
        $timestamp = time();
        
        $seats = $orderModel->where("course_id={$orderData['course_id']} and (({$timestamp} - create_time <= 900 and pay_status != 3) or  pay_status = 1)" )->column('seat');      
       
        $this->assign('admin_id',session('ADMIN_ID')); 
        $this->assign('courseList',$courseList); 
        $this->assign('orderData',$orderData);
        $this->assign('seats', implode(",", $seats));
        $this->assign('id',$order_id);
        $this->assign('data',$data);
        return $this->fetch();
    }

    public function editOrderSave()
    {
        $OrderModel = new OrderModel();
        $data = $this->request->param();   
        $orderData = $OrderModel->where('id',$data['id'])->find();   
        
        if (empty($data['seat'])) {
            $this->error("编辑失败，座位号不能为空！");
        } 

        $timestamp = time();
        $orderModel = new OrderModel();
        $status = $orderModel->where("course_id={$data['course_id']} and seat={$data['seat']} and (({$timestamp} - create_time <= 900 and pay_status != 3) or  pay_status = 1)" )->find();    
        
        if ($status) {
            if($orderData['course_id']!=$data['course_id'] && $orderData['seat']!=$data['seat']){
                $this->error("添加失败，{$data['seat']}号座位已被选");
            }                
        }        
        if($data['pay_status'] == 1){
            $data['pay_time'] = date('YmdHis');
        }
        if($data['pay_status'] == 3){
            $data['refund_time'] = time();
        }
        $result = $OrderModel->allowField(true)->isUpdate(true)->save($data);
        if($orderData['course_id']!=$data['course_id']){
            Db::name('school_course')
				->where('id','=',$orderData['course_id'])
                ->setDec('order_count',1);
                Db::name('school_course')
				->where('id','=',$data['course_id'])
                ->setInc('order_count',1);
        }
        if($data['pay_status']==3){
            Db::name('school_course')
				->where('id','=',$orderData['course_id'])
                ->setDec('order_count',1);
        }
          
        if ($result === false) {
            $this->error('编辑失败!');
        }

        $this->success('编辑成功!', url('AdminOrder/index'));

    }

    public function ajax_getCourseSeats(){
        $data = $this->request->param();      
        $orderModel = new OrderModel(); 
        $timestamp = time();
        $seats = $orderModel->where("course_id={$data['course_id']} and (({$timestamp} - create_time <= 900 and pay_status != 3) or  pay_status = 1)" )->column('seat'); 

        $courseModel = new SchoolCourseModel();
        $course = $courseModel-> where('id',$data['course_id'])->find(); 

        $data=array(
            'seats'=>implode(",", $seats),
            'num'=>$course['num']
        );

        return json_decode(json_encode($data));
    }

    public function microPay(){
        $data = $this->request->param();
        $OrderModel = new OrderModel();
        $courseModel = new SchoolCourseModel();
        $orderData = $OrderModel->where('id',$data['id'])->find();
        $courseData = $courseModel->where('id',$orderData['course_id'])->find();

        $this->assign('courseData',$courseData);
        $this->assign('orderData',$orderData);
        return $this->fetch();
    }
    public function ajax_pay(){
        $data = $this->request->param();
        $OrderModel = new OrderModel();
        $courseModel = new SchoolCourseModel();
        $orderData = $OrderModel->where('id',$data['id'])->find();
        $courseData = $courseModel->where('id',$orderData['course_id'])->find();
        
        $requestData = array(
            'appid' => 'wx22bd817e9339f253',
            'mch_id' => '1519151931',
            'nonce_str' => self::getNonceStr(),
            'body' => $courseData['title'],
            'out_trade_no' => $orderData['order_no'],
            'total_fee' => $orderData['price'] * 100,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
            'auth_code' => $data['auth_code'],  
        );
        $requestData['sign'] = $this->MakeSign($requestData);                
        $wxPay = Wxpay::microOrder($requestData);
        $result = Wxpay::FromXml($wxPay);
        if($result['return_code']=="SUCCESS" && $result['result_code']=="SUCCESS" && $result['trade_state']=="SUCCESS"){
            //获取服务器返回的数据
			$order_num = $result['out_trade_no'];         //订单单号			
			$transaction_id = $result['transaction_id'];  //微信支付流水号
			
			$online_transaction_no = array(
				'source' =>  'wxapp',     //支付来源
				'transaction_id'    =>  $transaction_id				
            );
            $status = Db::name('order')
			->where('order_no','=',$order_num)
			->update(['online_transaction_no'=>json_encode($online_transaction_no),'pay_status'=>1,'pay_time'=>$result['time_end']]);
			if($status){
				$course_id = Db::name('order')
				->where('order_no','=',$order_num)
				->value('course_id');

				Db::name('school_course')
				->where('id','=',$course_id)
                ->setInc('order_count',1);      
            }
        }
        return json_encode($result);
    }

    public function ajax_query_micro_order(){
        $data = $this->request->param();
        $requestData = array(
            'appid' => 'wx22bd817e9339f253',
            'mch_id' => '1519151931',
            'nonce_str' => self::getNonceStr(),                
            'out_trade_no' => $data['order_no'], 
        );
        $requestData['sign'] = $this->MakeSign($requestData);                
        $wxPay = Wxpay::queryMicroOrder($requestData);
        $result = Wxpay::FromXml($wxPay);
       
        if($result['return_code']=="SUCCESS" && $result['result_code']=="SUCCESS" && $result['trade_state']=="SUCCESS"){
            //获取服务器返回的数据
			$order_num = $result['out_trade_no'];         //订单单号			
			$transaction_id = $result['transaction_id'];  //微信支付流水号
			
			$online_transaction_no = array(
				'source' =>  'wxapp',     //支付来源
				'transaction_id'    =>  $transaction_id				
            );
            $status = Db::name('order')
			->where('order_no','=',$order_num)
			->update(['online_transaction_no'=>json_encode($online_transaction_no),'pay_status'=>1,'pay_time'=>$result['time_end']]);
			if($status){
				$course_id = Db::name('order')
				->where('order_no','=',$order_num)
				->value('course_id');

				Db::name('school_course')
				->where('id','=',$course_id)
                ->setInc('order_count',1);
            }
        }
        return json_encode($result);
    } 

    public function getOrderNo(){
        $no = '';      
        while(true){            
            $no = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
            $row = Db::name('order')->where('order_no',$no)->find();
            if(!$row){
                break;
            }
        }
        return $no;        
    }

    
    public function ajax_pay_refund(){
        $data = $this->request->param();        
        $OrderModel = new OrderModel();
        $courseModel = new SchoolCourseModel();
        $orderData = $OrderModel->where('id',$data['id'])->find();       
        
        $requestData = array(
            'appid' => 'wx22bd817e9339f253',
            'mch_id' => '1519151931',
            'nonce_str' => self::getNonceStr(),           
            'out_trade_no' => $orderData['order_no'],
            'out_refund_no' => $orderData['order_no'],
            'total_fee' => floatval($orderData['price']) * 100,
            'refund_fee' => (floatval($orderData['price']) - round(floatval($orderData['price']) * 0.006,2)) * 100,           
        );
        $requestData['sign'] = $this->MakeSign($requestData);                
        $wxPay = Wxpay::refundOrder($requestData);
       
        $result = Wxpay::FromXml($wxPay);
        
        if($result['return_code']=="SUCCESS" && $result['result_code']=="SUCCESS"){
            //获取服务器返回的数据
			$order_num = $result['out_trade_no'];         //订单单号			
            $refund_no = $result['refund_id'];  //微信退款流水号
            $refund_fee = $result['refund_fee'];
            $refund_time = time();
            $refund_description = '已退款到微信支付原账号';
            $online_refund_status = 1;
			
            $status = Db::name('order')
			->where(['order_no'=>$order_num,'pay_status'=>1])
			->update(['refund_no'=>$refund_no,'refund_fee'=>$refund_fee,'refund_description'=>$refund_description,'online_refund_status'=>$online_refund_status,'pay_status'=>3,'refund_time'=>$refund_time]);
			if($status){
				$course_id = Db::name('order')
				->where('order_no','=',$order_num)
				->value('course_id');

				Db::name('school_course')
				->where('id','=',$course_id)
                ->setDec('order_count',1);
            }
        }else{
            $refund_description = $result['err_code_des'];
            $online_refund_status = 2;

            Db::name('order')
			->where('order_no','=',$orderData['order_no'])
			->update(['refund_description'=>$refund_description,'online_refund_status'=>$online_refund_status]);
        }
        return json_encode($result);
    }

    /**
	 * 
	 * 产生随机字符串，不长于32位
	 * @param int $length
	 * @return 产生的随机字符串
	 */
	public static function getNonceStr($length = 32) 
	{
		$chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
		$str ="";
		for ( $i = 0; $i < $length; $i++ )  {  
			$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
		} 
		return $str;
    }
    /**
	 * 格式化参数格式化成url参数
	 */
	public function ToUrlParams($data)
	{
		$buff = "";
		foreach ($data as $k => $v)
		{
			if($k != "sign" && $v != "" && !is_array($v)){
				$buff .= $k . "=" . $v . "&";
			}
		}
		
		$buff = trim($buff, "&");
		return $buff;
	}
	
	/**
	 * 生成签名
	 * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
	 */
	public function MakeSign($data)
	{
        error_reporting(0);
		//签名步骤一：按字典序排序参数
		ksort($data);
		$string = $this->ToUrlParams($data);		
		//签名步骤二：在string后加入KEY
		
		$string = $string . "&key=2a336dc09120317722a8366b35051884";
		//签名步骤三：MD5加密
		$string = md5($string);
		//签名步骤四：所有字符转为大写
		$result = strtoupper($string);
		return $result;
    }
}
